Vous êtes sur la page 1sur 47

BODY GEOMETRY DATA 1

Body Geometry Data


Matthew J. Conn
California State Monterrey Bay & Specialized Bicycle Components Inc.
CST-499
5/15/2017
BODY GEOMETRY DATA 2

Executive Summary
Body Gemoetry Data is a web-application tool developed for Specialized Bicycle
Components Inc.. The web-application acts as a portal into a large data-source. Retl Inc., a
Subsidiary of Specialized Bicycle Components Inc.; provided the data-source for the project.
Retl develops and produces bicycle fitting software and hardware to aid bicycle retailers in
tailoring the fit of the bicycles ridden by their customers. As Retls product grows in
sophistication, so has their ability to record and store rider attributes. Retl has recently
developed a DSD measuring device. The device measures and digitally uploads the distance
between each riders sit-bones. The data-source provided for the project in .CSV format features
this sit-bone measurement as well as other associated rider attributes.
Retl is one of the many Data-Sources being constructed at Specialized Bicycle
Components. As the company strives further towards being the bicycle industry pioneer in Data-
Driven design; harnessing engineering insights is currently a big initiative that is just beginning.
The simple web-application Body Geometry Data is a piloting project. The goal was to build a
simple web-application to begin gathering insights from Retls data. The purpose of the project
is too gain insights on how to properly construct and implement an R&D Portal for gathering
engineering insights from not only Retl as a data-source, but also the many other data-sources
present at Specialized Bicycle Components. Some examples of other possible data-sources for
future development are the Win-Tunnel Specializeds in-house wind-tunnel, and the POS
system Specialized has set up in many of their global retail centers. The goal would be not only
to use data to design the fastest bikes possible, but also too make purchasing suggestions for
customers based on their prior purchases, fit-data, and personal riding style which will all be
under a central consumer account.
Engineers currently have no tool that can gather predefined insights from the large data-
source that is Retl. By starting off with a very simple tool for each desired insight, one-by-one
each data-structure required for the insights is defined. This project kicks off the large task of
defining the data-structures and software architecture that a larger more all-encompassing R&D
portal will require. Body Geometry Data is a pilot web-application, produced as an early
attempt to create a portal for engineers into Retls data. The production application will be
developed over the next 3 years and will encompass functionality for accessing data from many
more data-sources within Specialized Bicycle Components Inc..
BODY GEOMETRY DATA 3

Table of Contents:
Part 1:
Section 1.1: Introduction/Discussion
1.1.1: Problem and/or Issue in Technology.5

1.1.2: Solution to the Problem and/or Issue in Technology....6

1.1.3: Project Goals and Objectives7

1.1.4: Community & Stake-Holders....8

1.1.5: Evidence that the Project is Needed..8

Section 1.2: Feasibility Discussion...9

Part 2:
Section 2.1: Design Requirements

2.1.1: Functional Decomposition of the project..10

2.1.2: Selection of Design Criterion11

2.1.3: Final Deliverables..12

2.1.4: Approach/Methodology.14

Section 2.2: Design Considerations

2.2.1: Legal Considerations....15

2.2.2: Ethical Considerations..16

Part 3:

Section 3.1: Completing the Assignment

o 3.1.1. : Timeline & Budget...16


BODY GEOMETRY DATA 4

o 3.1.2. : Usability Testing & Evaluation18

Section 3.2: Preparing to turn in the assignment

o 3.2.1. : Final Implementations..19

o 3.2.2. : Conclusion24

References

Appendix:

Appendix 1.2.1: Example of Traditional Approach to Measuring Sit-Bones....28

Appendix 1.2.2: Scientific Term for Sit-Bones & Associated Anatomical

Structure....28

Appendix 2.1.1.1: Generating the ProperTable.....29

Appendix 2.1.1.2: The Basic Design.....29

Appendix 2.1.2.1: The UI Design......29

Appendix A: Usability Test-Plan...30

Appendix B: Team Member Roles & Responsibilities..30

Appendix C: Sample Code.....30


BODY GEOMETRY DATA 5

Part 1

1.1.1: Problem and/or Issue in Technology

For this Capstone Project the group partnered with the global engineering and design

firm, Specialized Bicycle Components or Specialized Bicycle Components. For this project, the

team will be building a database and a web-application to communicate with the database. This

particular Relational database currently only holds one table. Eventually, it will utilize at a

minimum of two tables. The most basic way to fulfill this systems purpose could be

accomplished using one Table. The database is constructed from data collected and stored by

Ret l Inc.; a subsidiary of Specialized Bicycle Components. At Specialized Bicycle

Components they are beginning to work closely with Ret l in an effort to bring data-driven

design to the cycling industry. Within the industry and the sport of cycling, the idea of

customizing the geometry of the consumer/racers bicycle using variations in component

specification; is of the utmost importance with regards to comfort and performance while riding.

Like it or not, saddle development within the cycling industry has been conceptualized and

quantified purely through tribal knowledge since the invention of the bicycle with pedal

and rotary cranks in 1861.. (ThoughtCo (Bellis), 2016). The most critical areas/components of a

bicycle with regards to comfort while riding, can be identified as those components that the rider

physically interfaces with. The way a bicycle interacts with a rider is based on two forms of

interaction. One as previously stated can be conceptualized as the physical interaction between

the rider and the components of the bike that he/she physically with their body; components like

saddles, pedals, gloves, grips, shoes, and the buttocks section of riding clothing that features

comfort pads. The other form of interaction between the rider and the bicycle that features
BODY GEOMETRY DATA 6

noticeable and definitive gains with regards to comfort and performance can be conceptualized

as the cohesiveness between the geometry of the particular bicycle and the geometry of the

particular human rider. In the past this symbiotic relationship led to innovations in bike-geometry

and component-design in a purely organic way. Saddle design has had a truly Darwin-esque

evolution. Designers have literally relied on trial and error since the first bicycles. Trial and Error

is a proper method because it relies on designing around averages. Humans vary in shape and

size to a great extent, and so there is no real proof of concept other than the reliance of past failed

designs. Due to the unique relationship and physical system that is formed by the bicycle and the

rider, there is a unique opportunity within the cycling industry to move beyond this reliance on

Tribal Knowledge towards one that is more Data-Driven. This concept is the reason why

Specialized Bicycle Components has invested in both a wind-tunnel and the subsidiary Retl.

Retl now has the capability to take Sit-Bone measurements of riders during their Retl Fit-

Sessions. For a visual and scientific explanation of what a sit-bone measurement entails please

refer Appendix 1.1.2.2 Scientific Term for Sit-Bones & Associated Anatomical Structure

(artscyclery.com, 2012). The Engineering Department at Specialized Bicycle Components

currently has no window/portal set-up for making custom queries against Retls precious data.

The need for such an interactive portal stems from the industry evolution that has led Specialized

Bicycle Components to invest in Data-Driven Design and associated developments.

1.1.2: Solution to the Problem and/or Issue in Technology

Retl has applied Data-Driven Design to Bicycle Fit at a Retail Level. Through

digitalizing old methods of measuring Rider Geometries, as featured in Appendix 1.1.2.1

Example of Traditional Approach to Measuring Sit-Bones (artscyclery.com, 2012); Retl has

opened the door to gathering Body-Geometry related data at a retail level. The project team has
BODY GEOMETRY DATA 7

been asked by both the Director of Software Engineering for Retl and the Director of Applied

Technologies to build a standard software architecture for making custom queries against the

Rider related Data and Attributes that Retl gathers from their Bike-Fitting Hardware that is

install in Specialized Bicycle Components Bicycle Retail Centers around the world. The team

has been provided a snapshot of a table in Retls database that supports Rider fit Sessions and

the associated Rider attributes for each Sit-Bone measurement taken. For each Session, three

measurements are taken. I It is required that the team sets up a simple database architecture and

supported UI for easily selected predefined custom queries. For this project the goal will be to

have a simple drop-down for selecting two or more insights drawn from querying Retls Sit-

Bone Measurements and associated Rider data through executing a UI embedded SQL-Script.

1.1.3: Project Goals and Objectives

The goal for the project is take the first step towards building an R&D portal for

engineers wanting insights from large data-sources. It is a great opportunity to build a simple

data architecture for the relatively simple Retl data-source. It is a good time to make this data

connection because Retl as a Big-Data source is still in somewhat of an infant stage in its

complexity. This early developmental stage allows the teamates to grow in architecture, skill,

and understanding in parallel with the sophistication of the data-source. Due to the minimal

initial sample-size, run-time optimization will remain slotted as least of all concerns. The first

step is constructing an interactive database. In order to do this it is necessary to choose a

database architecture. For this project the group will develop from the beginning in parallel with

both a combination of MySQL & PHP architectures and Apache Derby Architecture. Apache

Derby, a data base supportive sub-project of APACHEs web-server software, is an open

source relational database implemented entirely in Java Derby is based on the Java, JDBC, and
BODY GEOMETRY DATA 8

SQL standards... (APACHE.org, 2016). APACHE will allow the team to use the programming

language known best (Java) to set up connections with the APACHE-web-server holding the

Derby-database, issue Java-embedded SQL scripts for custom queries using JDBC-libraries, and

build a custom UI in a Java-based application.

1.1.4: Community & Stake-Holders

A Specialized Bicycle Components company motto states The Rider Is The Boss and

the founding principle is manifested through the founder Mike Sinyard stating that the company

is Founded on performance and fueled by innovation, our focus on the rider and their needs is

our constant. (Specialized.com, 2017). The impacts of the project will be witnessed more

immediately by the developers who will harness the engineering insights the project will procure

from Retls Body-Geometry data. The implications of being able to query body geometry

measurements of human riders from all over the earth will not only be felt by those consumers

within the cycling industry but also by the sports-medicine and medical communities of which

whom are only a few examples of intellectual institutions who could potentially benefit from the

data that Specialized Bicycle Components will procure later on through the help of a big-data

developer. Through building the initial R&D portal to gather engineering, medical, and sports

medicine related insights from the data, this project could have more grandiose and unforeseen

implications for riders and other humans alike.

1.1.5: Evidence that the Project is Needed

The project does not encompass an all-around solution for Saddle development. The

project instead, builds a gateway to gain engineering insights for the Specialized Bicycle

Components teammates in the Engineering, Applied Technologies, and Marketing departments.


BODY GEOMETRY DATA 9

As Retls capabilities grow to store the data they are collecting in retail stores worldwide, so

also will the engineering and design insights grow exponentially in comparison. Imagine having

a database full of Body-Measurement data and associated rider attributes. As Retls capabilities

to gather the data and store it are growing rapidly; having a dedicated developer that is able to

extract data from this data-source in a quick, dynamic, and one-off manner may be useful for the

department. This Project will solve the problem at Specialized Bicycle Components manifested

through the lack of an Specialized Bicycle Components R&D Data-Portal into Retls Rider

associated Data-Source by querying insights from one of Retls initial Rider associated

attributes engines, Retl as a Data-Source.

1.2.1: Feasibility Discussion

There is a positive marketplace for the data-driven technology we can create if

Specialized Bicycle Components can gain insights from Retls Body Geometry data. There will

always be a market for new innovations in this market, especially those that encompass data-

driven design rather than a traditional organic trial-and error approach. This need for innovations

in cycling fit technology is rooted in the riders need for their bicycle to be better tuned

specifically for their unique body. Within the cycling community it is understood that the way

your bicycle fits your unique shape and body, is of utmost importance with regards to bicycle

performance and comfort. Many beginner cyclists attempt to adjust the fit of their bike by

themselves. This can be done by adjusting saddle height & pitch of saddle, and distance of saddle

to the front axle in a plane parallel to the ground. Also riders can hone in on their fit by

adjusting the length of their stem, the width of their handle-bars, the length of their crank arms,

and the angle at which the stem reaches from the Forks steerer-tube to the handle-bars. Making

these adjustments yourself is quite difficult. The importance of fit to the rider is extremely
BODY GEOMETRY DATA 10

important with regards to comfort and health, you might even be doing yourself some damage

in the longer term if your steed isnt correctly set up to suit your body. (The-Telegraph 2017).

Attempts to revolutionize bicycle fit understanding and execution have been a key focus of

bicycle development since the first bicycle was produced. Bicycle fit related innovations are

common, querying a global sample of rider related body geometry measurements and associated

attributes is one-of-a-kind. This type of data-connection has never been used before in the

cycling industry to gain engineering and design insights from rider-related Big-Data. Due to

the uniqueness of the data being analyzed the team has decided to take multiple design

approaches. Since a project like this has not been attempted in the cycling industry the team will

start by developing two architectures in parallel, one that features MySQL database architecture

and one that features APACHE web-Servers Derby DB architecture. According to APACHE.org,

Derby architecture allows the developer to utilize an embedded JDBC driver that lets you embed

derby in any Java-based solution. (APACHE.org, 2016) Both in theory will work however if the

team is able to build a UI too access the database-connection functionality featured in APACHE

Derby architecture, it will be the project development teams preference and the team will be

swift to cease MySQL and PHP development.

Part 2

2.1.1: Functional Decomposition of the Project

For this project the team has been able to add more functions to the design than

originally required. Initially, the basic design required one main function. The basic design

requires that the software query a database for the average sit-bone measurement of both males

and females. The original data-source provided to me by Retl Inc. features session-id for each
BODY GEOMETRY DATA 11

rider who is measured during their bicycle fitting at a retail center. Each of these fitting sessions

feature anywhere from 2 to 5 sit-bone measurements. If each session were to feature a uniform

number of measurements, then you could find the average sit-bone measurement from the entire

set. In-order to find the true average the team created a custom query that returns the average of

all measurements per session-id in a new table entitled propertable. The SQL statement I

formulated to generate this new table can be seen in Appendix 2.1.1.1 (Generating the

ProperTable) below. This new propertable is the foundation for the basic design of the project

and will allow the possibility of fulfilling the projects required function to display the average

sit-bone measurements for men and women. As the project grows in complexity it will continue

to rely on the propertable to return accurate average measurements. The original basic design

simply queries the database upon run-time and displays the averages to the browser window for

the user to view. The basic design can be seen below in Appendix 2.1.1.2. (The Basic Design).

2.1.2: Selection of Design Criterion

Due to the early completion and achievement of preliminary design requirements, it was

decided to expand upon the more basic preliminary design. Originally, the basic-requirement was

to merely build web application to query and hold both average sit-bone measurements for all

women and men. As a result of having more rider attributes (fields in the database) than what is

necessary to achieve the basic-requirement; it was possible to feature even more detailed sit-bone

measurement averages and insights. Professional experience in a design and engineering

environment will reflect that it is always easier to determine one line of data rather than a very

large sample set. The Basic-Design of the program was limited to querying sit-bone

measurements against two fields (gender & saddle-width) and thus all returned values could be

featured in a relatively small table for the userss viewing. To expand the functionality of the
BODY GEOMETRY DATA 12

form to encompass a querying these measurements against 5 fields instead of two makes it

tougher to feature the desired averages because their sample size grows exponentially with each

field queried against. The final design for the program will be referred to as The UI Design

because it features a User-Interface. The UI Design can be viewed in Appendix 2.1.2.1. (The UI

Design) below. Because the possible sample-size of returned averages could be much larger, a

User-Interface has become necessary. Instead of listing out all average sit-bone measurements by

the fields used to query them; it was decided to have the user choose which fields they care

about. The possible fields to query by are now gender, saddle width, ride-frequency, category,

and ride-duration. For any given field the user may choose all possible options or none to be

queried against. For the UI design, the web-application will return one desired sit-bone

measurement average per query (queries are executed upon clicking the submit button) which is

easier to look at than the Basic-Design. Another major difference between the two designs is

their architecture. Building a UI-based web-application that parses together SQL statements

based off of User-Input requires more advanced architecture than merely displaying text in an

HTML file and hosting it on a server. When choosing to pursue and implement The UI Design,

the team had to come to grips with the fact that it would be much harder to implement than The

Basic Design.

2.1.3: Final Deliverables

The final deliverables for this project will be the basis for further development on the

web-application. For the capstone project, the final deliverable will be a functioning version of

the Sit-Bone Measurement web-application hosted locally using a Tomcat v7 Server. The team

will present for the capstone project some tutorial and demo runs of the web-application. The

team will then show a false database which will accurately reflect the fields featured in the actual
BODY GEOMETRY DATA 13

database used to drive the web-application. The reason for showing a false database with

dumby data populating it instead of actual rider data is to protect this personal information

belonging to the riders measured and Specialized Bicycle Components. By showing the fields

and queries used to create the ProperTable, it will show the teams in-depth understanding of

database logic and design. Thus concludes the summary of the final deliverables for the

Capstone Project. Once the Project is completed the teamI will go on to build further

functionality to support potential users within Specialized Bicycle Components. The potential

user for the web-application will be Saddle-Design-Engineers at Specialized Bicycle

Components. For ease of use, the team will migrate the web-application to be hosted within a

confluence-page on Specializeds private instance of the software.

The engineer will use the application to refer to sit-bone averages for riders that fall

within each selected attribute (field). For ease-of-use and security, the web-application needs to

be made available to the engineer when they are logged into Specialized Bicycle Components

VPN. On our VPN here at Specialized we have a privately hosted instance of Confluence and

Jira. It has been chosen to embed the web-application into a confluence page while utilizing a

reverse proxy server. This design choice has two main implications for the end user. The first

implication being that the insights gained and accessible through the web application must

remain secure on a Specialized hosted Server, the companys private instance of confluence is

hosted on such a server, which will allow security features of the web-application to be piggy-

backed off of those already implemented by the privately (in-house) hosted confluence server.

According to Atlassian inc. (Australian developing firm that owns rights to Jira & Confluence),

You might consider using a reverse proxy when you want users to access the Atlassian

applications: ..on different HTTP ports, such as 9800, 9850, etc.. (Atlassian, 2017) Since
BODY GEOMETRY DATA 14

Specialized Bicycle Components is hosting the server hosts our instance of confluence, the

design team can use a local port to embed the web-application into a confluence page.

2.1.4: Approach & Methodology

For this project the approach and methodology are truly expressed through the

architecture of the overall web-application. Since the beginning of the project three separate

approaches have been taken and subsequently three separate architectures have been explored.

Each architecture features three main components a chosen database architecture/framework, an

open-source TomCat server, and some sort of embedded scripting language to issue the SQL

statements to the database hosted on the TomCat server. For the first attempt an architecture

featuring a Derby DB (Subproject of APACHE web-server software for hosting databases)

database hosted on a APACHE TomCat server was to be communicated using a java-based

application (using support for JDBC-libraries). This architecture was hard to implement. Getting

all versions of Java JREs and JDKs in order proved tricky and a new architecture was soon

sought out. For the second architecture a more traditional approach was taken. Similarly a

TomCat server was utilized to host a MySQL database on a local port. According to Oracle Inc.,

A JSP page is a text document that contains two types of text: static data, which can be

expressed in any text-based format (such as HTML, SVG, WML, and XML), and JSP

elements, which construct dynamic content.. (Oracle 2010)

In addition to holding XML and HTML, these files can also hold embedded SQL statements.

Instead of relying on the Derby DB plugin, it was chosen to use a .JSP file to hold the

appropriate HTML and embedded SQL statements for communicating with the database on the

server. This architecture was executed in The Basic Design of the project. It was decided to
BODY GEOMETRY DATA 15

use an new architecture to develop The UI Design, in order to support better user-interaction

with the form. This new architecture also features a MySQL database hosted locally on a

TomCat server as well as, a .JSP page for displaying content to whatever browser is executing

the HTML for the web-application. Additionally, a servlet was constructed so that user-input

could be assigned to variables and then parsed/constructed into the appropriate SQL statement

that will query and return the Users desired result. This is the architecture that was chosen to

move forward with because it has the key features needed to turn a simple reporting page for

queried results into a User-Interface based web-application.

2.2.1: Legal Considerations

There are minimal legal risks involved with a project of this nature due to three core

attributes involved. The first project attribute rendering it a low legal threat and consideration is

the fact that Specialized Bicycle Components Inc. owns all of the data that is being worked with.

Riders give the data willingly during their fit sessions and are made aware that the data may be

used for design. At no point has this data ever been taken unlawfully. The second project

attribute which renders it low-risk from a legal standpoint, is the fact that the security

encompassing the web-application is more than efficient. Through hosting the web-application

locally over the Company VPN, the team can rely on the strength of the server on the network

holding the application. The third attribute rendering the project a low security risk with regards

to legal considerations, can be found in the nature of the database to not rely on security sensitive

information. Retls database holds thing such as names and cycling details, Riders SSN

numbers are not stored and neither is any banking information. It is essentially all such

specialized focus data that a minimal amount of hackers would ever considering stealing it. By

featuring fields in the hosted database that strictly do not hold security sensitive information
BODY GEOMETRY DATA 16

pertaining to riders, it is easy to cut-down on security threats due to the undesirability of the data

being stored.

2.2.2: Ethical Considerations

The ability to access data within the sports-medicine and sports-entertainment/recreation

industries, has proven to be paramount in the evolution of our understanding as humans of our

physical vessels that are our bodies and physical form. The way athletes prepare has changed

devastatingly so due to sports-analytics. It has changed everything from how athletes approach

competition with their competitors, to how sports industry executives decide whom to contract

for their team. According to Leigh Steinberg of Forbes Magazine Today, every major

professional sports team either has an analytics department or an analytics expert on staff.

(Steinberg 2015). The same holds true for cycling teams. Cycling as a sport is generally 4 to 5

years behind in technology that is featured in more mainstream American Sports. The insights

and implications of Big-Data and analytics are just now being explored and conceptualized in the

cycling world. Team members have personally worked on projects to design and 3D-Print

attachable housings for RFID live feedback during UCI bicycle races. Such devices are used to

give enthusiasts and viewers around the world live updates to Rider Stats. The excitement of

applying insights drawn from Big-Data to improve the lives of Bicycle Riders through making

better saddles fueled the desire to chose this project as the groups Capstone.

Part 3

3.1.1: Timeline & Budget

For this project, budget was not the main concern and development was more driven by

the timeline. Budget was of little concern because the project did not require any capital
BODY GEOMETRY DATA 17

investments. Timeline was of huge importance to this project because it played a role in shaping

the final deliverables. The project has featured an AGILE approach to development, and added

functionality was realized through having an established timeline with defined milestones. As a

manifestation of the flexibility provided by AGILE development and the lack of restraints from a

defined budget; the proposed final deliverable changed throughout the project with each

milestone/iteration released on a weekly schedule. The first Milestone met was building a

Database Management System architecture that could feature and run SQL statements against a

MySQL database featuring Retls data. This first milestone was realized using a TomCat web

server in conjuction with a MySQL database and one sole .JSP file to query and publish results

to HTML. The next iteration and milestone was manifested and fulfilled by adding the

functionality of a Servlet to create a UI for the client facing web-application. This iteration used

.JSP in conjuction with Java Servlet functionality. The UI allows the client to select a more in-

depth query based on additional fields that were not featured in the first iteration of the project. A

third milestone would be fully testing and debugging the web-application using the UI for unit

testing. The only milestone that was not met was not an actual project requirement. The original

desire was to build a NoSQL based web-application for querying the database. A NoSQL

database architecture would be more scalable in the future after project completion. The team

was unable to implement a NoSQL database architecture due to configuration restraints. The

restraints are driven by the fact that the project was built using a Specialized Bicycle

Components owned computer. This computer has the wrong version of Java JREs and SDKs

needed to support NoSQL architecture. The JREs and SDKs installed on the machine cannot

change due to some of the software the company uses universally for all employees. In the near

future the project will be converted to feature a NoSQL database architecture.


BODY GEOMETRY DATA 18

3.1.2: Usability Testing & Evaluation

Usability Testing was executed during each week of the project, for each iteration

released. The first usability challenge was configuring all aspects of the application architecture

to work together. During this time it took several tries to implement the architecture with regards

to configuration restraints, these restraints were not fully realized until the implementation phase

was underway. The implementation phase would begin again during the development of the UI

design. During this time it was crucial to establish the correct Java files to support UI

functionality. While observation and corrections continued with regards to architecture

throughout the entire project, debugging and testing the web-application also happened for each

iteration that featured new functionality. The initial debugging of the Basic Design was

manifested through data-validation efforts executed on the database table constructed from the

original .CSV file containing Retls Sit-bone measurement and associated data. Since the goal

of the project was to return the average IT-width (sit-bone measurement) for each gender male

and female. The original .CSV file featured a range of 2-4 IT-width measurements taken for each

Retl Fit session. In order to return an accurate average measurement, it was first necessary to

reconstruct the table using the session id as a primary key. In order to do this it was imperative

that the IT-width field associated with each session-id be changed to an average IT-width field.

Without constructing a new table (the properTable) with this validation it is impossible to query

accurate average measurements from the database. With regards to debugging both the basic

design and the UI design, it was fruitful to know one key constant design parmater. Knowing the

sample-size of session-ids provided by Retl allows the designer of both UIs to debug whether or

not the entire sample size is being taken into consideration when returning query associated IT-

Width average measurements. In this way the UI design became its own Unit-testing tool.
BODY GEOMETRY DATA 19

Another precaution taken with regards to checking and testing the average measurements

returned was executed using the .CSV file provided from Retl. By using a combination of VBA

and FormCalc to custom modify and define excel macros to procure the same average values

featured in the UI design of the project. Every possible output has been tested and validated. The

program cannot be broken by faulty input because input from the user is only gathered from

selecting radio-buttons, there are no free-text entry fields for the client to fill-out. Outside of Unit

Testing and configuration analysis, implementing the UI design posed other challenges with

regards to publishing and demoing the web-application in a public forum. One of the restraints

put on the project by Retl and Specialized Bicycle Components, is that the insights derived and

the data provided must not be shown during the presentation. In order to do this the team decided

to construct yet another table, the falseTable. The falseTable has been constructed to show

similar data to that of the properTable however, scripts have been run against this data to de-

validate it. For example the team switched the riding-duration, riding-frequency, and category

fields for many session-ids so that when these fields are used to query average IT-Width

measurements, the average values returned appear to be accurate results (they carry what the user

sees as an expected value and format) but are in fact not based on accurate data. In this way the

team can use a version of the web-application that issues SQL statements against the falseTable

instead of the properTable during the project presentation demo.

Section 3.2: Preparing to turn in the assignment

3.2.1. : Final Implementations

At the beginning of the project the general understanding held true that Retl had recently

implemented a new design into their interactive bicycle fitting station. These stations are present

at all retailers globally where Retl Fit sessions are available. The new design implemented
BODY GEOMETRY DATA 20

within the fit station is commonly referred to as the DSD measurement device. This device uses

takes a pressure mapping of the riders pelvic region while sitting on the device. With the help of

a well thought out algorithm, the fit station is able to return an IT-width measurement. The

original state of this data before the formulation of this project, could be described as an island.

engineers at Specialized Bicycle Components lacked all visibility to the DSD measurement data.

As this is undoubtedly the first innovation in gathering large data-sets of measurements taken

from the physical bodies of riders, Retl will continue to build out their infrastructure to gather

other measurements as well. The idea was to get ahead in the early stages by building a simple

portal web-application into the data for engineers to gather insights. By starting with a simple

relational database, the team was able to build the initial UI and underlying architecture of an

R&D portal into Retls rider measurement database. Given a sole snapshot of Retls data for

the initial 4,049 fit sessions in .CSV format; the project succeeded in hosting the data in a

MySQL database hosted on a TomCat server. The project also succeeded in building the overly

web-application architecture in the form of a Java servlet and .JSP based web page; that was

necessary to construct a UI for engineers to use.

Due to early success in the most minimal of implementations, the project took on desired

added functionality within its third iteration. The original deliverable for the project was

described as building a web-portal to display average male and female IT-width measurements

for all riders of both genders. However, the original data-set provided by Retl featured

additional fields. It was decided that the project would expand its requirements. The new

requirements include development of added functionality to construct SQL statements from

User/Engineer input to not only return average IT-width measurements for both genders, but also

for user selected additional fields such as average riding-duration and average riding-frequency.
BODY GEOMETRY DATA 21

The necessity for a UI manifested organically due to these added requirements. In order to

implement a UI a new architecture needed to be implemented. This architecture would need to

add the functionality of a Java Servlet based web-application to the original Basic Designs .JSP

client facing web-page.

It was decided that the architecture of the web-application would reflect the Model View

Controller design pattern. Model View Controller is a design pattern featured in the coursework

of the CSIT program at California State University at Monterrey Bay. In this design pattern

objects are assigned one of three roles Model View or Controller. These roles define the purpose

of each object and how it interacts with other objects featured in the application. Apple

Developer publications provides a brief overview of how each Object should be configured in an

application featuring the Model View Controller design pattern;

Communication: User actions in the view layer that create or modify data are

communicated through a controller object and result in the creation or updating of a

model object. When a model object changes (for example, new data is received over a

network connection), it notifies a controller object, which updates the appropriate view

objects. (Apple Developer, 2015)

The Model Object was defined as a Plain Old Java Object (POJO) in its filename

SitBoneAnalysisResultPOJO.java. The Model Object was used to define and hold the data

specific to the function of the application. The View object was implemented as a combination

of the DataManager.java object and the .JSP file used to construct the HTML based client-facing

web page. This object was responsible for taking User Input in and using it to construct a SQL

statement to be ran against the database. The Controller object for the web-application was

present in the form of the QuerryController.java object. This object is passed the data reflecting
BODY GEOMETRY DATA 22

user-input and returns the strings necessary to the View object for constructing the SQL

statement. Additional design related decisions were made with regards to the UI to save time in

the testing and debugging of the web-application. An example of this is made evident in the in

the choice made to feature checkboxes to gather User/Engineer input. By using a commonly

recognized web application design pattern such as Model-View-Controller, Specialized Bicycle

Components will have less trouble migrating to a NoSQL based web-application later on. Using

recognized design patterns helps outside developers to maintain and further develop applications

later on.

The presentation itself will require extra-care and its own revision of the web-

application. The data stored in the properTable and originalTable are owned by Specialized

Bicycle Components and Retl. It will be important to protect the engineering insights produced

within the web-application during the presentation. In order to achieve a secure and presentation

friendly version of the web-application the team will alter the contents of the underlying table.

This new table is referred to as the falseTable. Various changes were made to the data in the

falseTable by changing attribute values for each of the fields. This was done by running a script

against the properTable in .CSV format to produce the falseTable. In this way the presentation

version of the web-application will produce results that appear to be real. The results in this

farlse version of the application will in fact hold no engineering value. In this way the

presentation can accurately demo the functionality of the web-application without surrendering

the engineering insights gained to the public eye.

The web-application has been rolled-out to the clients. The project was featured to an

audience of the CIO of Specialized Bicycle Components, Jerry McGlynn and the Director of

Applied Technologies at Specialized Bicycle Components, Chris Yu. Before beginning the
BODY GEOMETRY DATA 23

project there were a number of proposed projects from different Clients at Specialized Bicycle

Components. Jerry and Chris both felt that this was the project that held the most value for the

company at this point in time. While presenting the web-application to Jerry and Chris, future-

state became the main topic. While the web-application defines the data structure required to

look at Retls data its dependence on a relational database will need to be addressed. The client

feedback was that this project was a good first step towards defining what will be the R&D

Portal for the engineering and applied technologies groups at Specialized Bicycle Components.

Also in this meeting next steps toward building the R&D Portal were defined. It was decided that

the underlying database needs to be graph and NoSQL based instead of relational and based in

MySQL. The reason for this is not pertaining particularly to the structure of Retls data-set but

instead NoSQL will be required due to the numerous other data-sets within the company that will

need to be supported by the R&D Portal. Not only will we build a web-application portal into

Retls data-source, but we will also build a portals into our Test-Labs data-source and our

Retail POS system. These are only a few examples of the data-sources within the company that

we believe hold engineering insights. The general conclusion from the project presentation to the

clients is that the requirements were met, and to start taking steps towards building the same

web-application on-top of a NoSQL database system. Using a MySQL relational database was

deemed appropriate for analyzing Retls data-set, and it require minimal configuration to set-

up; but as we begin to include other Data-sources in the R&D Portal Specialized Bicycle

Components will need to switch to a new architecture featuring a document based NoSQL

database system.
BODY GEOMETRY DATA 24

3.2.2. : Conclusion

At the beginning of the project the Engineering Department at Specialized Bicycle

Components currently had no window/portal set-up for making custom queries against Retls

data. The deliverable to the client has been fulfilled in the web-application produced over the

course of the project. In-order to build this web-application solution four key challenges needed

to be overcome. The first challenge manifested from the process of selecting an architecture for

the web-application and underlying database. Originally the desire was to develop a NoSQL

database using Derby DB. Derby DB is a subproject of Apaches web-server application. It was

later decided to use a traditional relational database instead, due to configuration restraints on

Specialized Bicycle Components -owned computers. The second challenge arose from the

necessity of data-validation. Originally it was thought that the average IT-width measurements

could be taken straight from the originalTable (original data-set provided by Retl). After further

analysis the necessity of a properTable was proposed. Originally for each fit session-id there was

a varying amount of measurements taken. The average of the measurements for each fit session-

id were taken and featured in the new properTable, instead of featuring a record for each

measurement. In this was data-validation was executed by building an altered table to run SQL

statements against. The third challenge was taken on when it was decided to switch from the

Basic Design to the UI Design. This decision was made as an effort to exhaust all beneficial

engineering insights from the data. While the Basic Design publishes the average sit-bone

measurements (IT-widths) for both genders male and female, the UI Design allows the user to

have average measurements returned for more in-depth categories of riders. The UI Design

harnesses the entirety of fields associated with each session-id, instead of just merely focusing

solely on the gender attribute. The fourth challenge that was overcome was found in debugging
BODY GEOMETRY DATA 25

and producing a presentation-friendly version of the web-application. Debugging the web-

application was fairly simple due to two reasons. The first being the static sample-size of the

database, it was easy to double check that each 4,049 records were being looked at using the UI.

Creating the falseTable for the presentation version of the application was more difficult. A

custom script was written to alter all records of the data-set. This was done in a custom VBA

macro in excel. The macro was ran against the .CSV file before it was re-imported back into the

database management tool MySQL Workbench. While many challenges were overcome in

executing the project, It is evident that even more challenges will manifest in further

development of the web-application as it gets migrated to a NoSQL back-end database

architecture. The project was a success, and has led to an ongoing relationship with the client.

The project will continue on after the capstone presentation. The web-application will grow in

complexity to be an actual engineering tool for bicycle and component developers at Specialized

Bicycle Components Inc..


BODY GEOMETRY DATA 26

Resources:

Apache.org. (Oct. 29th, 2016). What is Apache Derby? Apache Derby. (Issue: 09:31:04).

Retrieved From: https://db.apache.org/derby/\

Apple Developer. (2015). Guides and Sample Code Model-View-Controller. Retrieved From:

https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia

-CocoaCore/MVC.html

ArtsCyclery Inc.. (Dec. 11th, 2012). Measure Sit Bone Width For Saddle Selection. How To:.

[images taken from embedded youtube video].

Retrieved From: http://www.artscyclery.com/learningcenter/measuresitbonewidth.html

(Youtube Video Location: https://www.youtube.com/watch?v=E7j9LUVJrjA)

Attlasian Inc.. (2017). Proxying Atlassian server applications with Apache HTTP Server

(mod_proxy_http). Attlasian Knowledge Base. Retrieved From:

https://confluence.atlassian.com/kb/proxying-atlassian-server-applications-with-apache

httpserver-mod_proxy_http-806032611.html

Bellis, Mary. (Nov. 29th, 2016). History of the Bicycle. History & Culture. Retrieved From:

https://www.thoughtco.com/history-of-the-bicycle-1991341

Oracle Inc. (2010). The Java EE 5 Tutorial. Retrieved From:

https://docs.oracle.com/javaee/5/tutorial/doc/bnagy.html

Specialized Bicycle Components Inc.. (2017) Our Mission. About Us. Retrieved From:

https://www.specialized.com/us/en/about-us
BODY GEOMETRY DATA 27

Steingberg, Leigh. (Aug. 18th, 2015). CHANGING THE GAME: The Rise of Sports Analytics.

Sports Money. Retrieved From:

https://www.forbes.com/sites/leighsteinberg/2015/08/18/changing-the-game the

rise-of-sports-analytics/#71e9514a4c1f
BODY GEOMETRY DATA 28

Appendix

Appendix 1.1.2.2: Scientific Term for Sit-Bones & Associated Anatomical

Structure

Appendix 1.1.2.1: Example of Traditional Approach to Measuring Sit-Bones


BODY GEOMETRY DATA 29

Appendix 2.1.1.1: Generating the ProperTable

Appendix 2.1.1.2: The Basic Design

Appendix 2.1.2.1: The UI Design


BODY GEOMETRY DATA 30

Appendix A:

Usability Test-Plan:

1. Validate incoming data using properTable to render the session-id field as a true primary

key.

2. Build UI-Design to support are all available attributes.

3. Use Static Sample Size to debug parsed SQL statement.

4. Create falsetable for the project presentation.

Appendix B:

Roles & Responsibilites

Matthew Conn is responsible for 100% of the work that went into this project.

Appendix C:

Source Code

QueryController.java:

package com.mine.demo.sample.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
BODY GEOMETRY DATA 31

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.mine.demo.sample.data.DataManager;
import com.mine.demo.sample.model.QueryRequest;
import com.mine.demo.sample.model.QueryRequestOptions;
import com.mine.demo.sample.model.SitBoneAnalysisResultPOJO;

/**
* Servlet implementation class DemoAverage
*/
@WebServlet("/averages")
public class QueryController extends HttpServlet {
private static final long serialVersionUID = 1L;
DataManager dataManager = new DataManager();

/**
* @see HttpServlet#HttpServlet()
*/
public QueryController() {
super();
// TODO Auto-generated constructor stub
}

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
BODY GEOMETRY DATA 32

throws ServletException, IOException {

// Get query parameters (from Request's parameters (View)


String genders[] = request.getParameterValues("gender");
Map<String, String> genderMap = new HashMap<String, String>();
if(genders != null) {
System.out.print("Selected gender/s: ");
for (String gender : genders) {
genderMap.put(gender, "on");
System.out.print(gender + ", ");
}
System.out.println();
} else {
System.out.println("null genders");
}

String saddleWidths[]= request.getParameterValues("saddleWidth");


Map<String, String> saddleWidthMap = new HashMap<String, String>();
if(saddleWidths != null) {
System.out.print("Selected saddleWidth/s: ");
for (String sw : saddleWidths){
saddleWidthMap.put(sw, "on");
System.out.print(sw + ", ");
}
System.out.println();
} else {
System.out.println("null saddleWidths");
}

String rideFreqs[]= request.getParameterValues("rideFreq");


BODY GEOMETRY DATA 33

Map<String, String> rideFreqMap = new HashMap<String, String>();


if(rideFreqs != null) {
System.out.print("Selected rideFrequency/s: ");
for (String rf : rideFreqs){
rideFreqMap.put(rf, "on");
System.out.print(rf + ", ");
}
System.out.println();
} else {
System.out.println("null rideFrequencies");
}

String rideCategory[]= request.getParameterValues("rideCategory");


Map<String, String> rideCategoryMap = new HashMap<String, String>();
if(rideCategory != null) {
System.out.print("Selected rideCategory/s: ");
for (String rf : rideCategory){
rideCategoryMap.put(rf, "on");
System.out.print(rf + ", ");
}
System.out.println();
} else {
System.out.println("null rideCategory");
}

String rideDuration[]= request.getParameterValues("rideDuration");


Map<String, String> rideDurationMap = new HashMap<String, String>();
if(rideDuration != null) {
System.out.print("Selected rideDuration/s: ");
for (String rf : rideDuration){
BODY GEOMETRY DATA 34

rideDurationMap.put(rf, "on");
System.out.print(rf + ", ");
}
System.out.println();
} else {
System.out.println("null rideDuration");
}

// Get Query Request from session info


HttpSession session = request.getSession(true);
QueryRequest queryRequest = (QueryRequest)
session.getAttribute("queryRequest");
if (queryRequest == null) {
queryRequest = new QueryRequest();
}

// Set up "next" request (for JSP View)


// (from defaults and previous attributes selected)
queryRequest.setWhat(QueryRequestOptions.SIT_BONE_MEASURE);

queryRequest.setResultType(QueryRequestOptions.AVERAGE_AND_COUNT);

queryRequest.setGenderOptions(genderMap);
queryRequest.setSaddleWidthOptions(saddleWidthMap);
queryRequest.setRideFreqOptions(rideFreqMap);
queryRequest.setRideDurationOptions(rideDurationMap);
queryRequest.setCategoryOptions(rideCategoryMap);

// Put "next" request info into Session


BODY GEOMETRY DATA 35

session.setAttribute("queryRequest", queryRequest);

// Get analysis results (model) from Database


SitBoneAnalysisResultPOJO analysisResult =
dataManager.getSitBoneAnalysisResult(queryRequest);

// Put analysis results into Session


session.setAttribute("sbAnalysisResult", analysisResult);
//session.setAttribute("results", averages);

// Dispatch to jsp to get "next" Request


RequestDispatcher dispatcher =
request.getRequestDispatcher("/queryResult.jsp");
dispatcher.forward( request, response);
}

/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}

DataManager.java:
package com.mine.demo.sample.data;
BODY GEOMETRY DATA 36

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.mine.demo.sample.model.QueryRequest;
import com.mine.demo.sample.model.SitBoneAnalysisResultPOJO;

public class DataManager {

/*
* Open database connection
*/
public Connection getConnection() {
Connection conn = null;
try {
// This will load the MySQL driver, each DB has its own driver
Class.forName("com.mysql.jdbc.Driver");
// Setup the connection with the DB
conn = DriverManager

.getConnection("jdbc:mysql://localhost/bodygeometrydata?" +
"user=root&password=xxxxxxxxxxxxxxxxxxxx");

} catch (SQLException e) {
System.out.println("Could not connection to DB");
e.printStackTrace();

} catch (ClassNotFoundException e) {
BODY GEOMETRY DATA 37

System.out.println("Could not load MySQL Driver");


e.printStackTrace();
}
return conn;
}

/*
* Close an open database connection
*/
public void closeConnection(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
System.out.println("Unable to close DB connection");
e.printStackTrace();
}
}
}

public SitBoneAnalysisResultPOJO getSitBoneAnalysisResult(QueryRequest


queryRequest) {
SitBoneAnalysisResultPOJO pojo = new SitBoneAnalysisResultPOJO();
pojo.setQueryRequest(queryRequest);

if (queryRequest == null ||
(queryRequest.getGenderOptions().isEmpty() &&
queryRequest.getSaddleWidthOptions().isEmpty() &&
queryRequest.getRideFreqOptions().isEmpty() &&
queryRequest.getRideDurationOptions().isEmpty() &&
BODY GEOMETRY DATA 38

queryRequest.getCategoryOptions().isEmpty())
){
System.out.println("No options set for Query");
return pojo;
}

Connection connect = getConnection();


if (connect != null) {
ResultSet rs = null;

String averagesQuery = getSessionAveragesQuery(queryRequest);


/*
StringBuffer averagesQuery = new StringBuffer();
averagesQuery.append("SELECT AVG(session_average) AS average,
COUNT(session_count) AS count");
averagesQuery.append(" FROM (").append(averagesQuery).append(") AS
averages");
*/
System.out.println(averagesQuery.toString());

PreparedStatement preparedStatement = null;


try {
preparedStatement =
connect.prepareStatement(averagesQuery.toString());

rs = preparedStatement.executeQuery();

while(rs.next()) {
pojo.setAvgMeasure(rs.getString("average"));
BODY GEOMETRY DATA 39

pojo.setHowManyMeasures(rs.getString("count"));
System.out.println("Results: " +
pojo.getAvgMeasure() + ", " +
pojo.getHowManyMeasures());
}

} catch (SQLException ex) {


ex.printStackTrace();

} finally {
try {
rs.close();
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return pojo;
}

private String getSessionAveragesQuery(QueryRequest queryRequest) {


StringBuffer averagesQuery = new StringBuffer();
averagesQuery.append("SELECT AVG(AVG_it_width) AS average,
COUNT(AVG_it_width) AS count");
averagesQuery.append(" FROM falsetable");
averagesQuery.append(" WHERE (");

if (queryRequest.getGenderOptions() != null &&


queryRequest.getGenderOptions().size() > 0) {
// Build gender clause
BODY GEOMETRY DATA 40

averagesQuery.append("(gender IN (");
if
("on".equalsIgnoreCase(queryRequest.getGenderOptions().get("female"))) {
averagesQuery.append("\"female\",");

}
if ("on".equalsIgnoreCase(queryRequest.getGenderOptions().get("male")))
{
averagesQuery.append("\"male\",");
}
if (averagesQuery.lastIndexOf(",") >= 0) {
averagesQuery.deleteCharAt(averagesQuery.lastIndexOf(","));
}
averagesQuery.append("))");
} else {
averagesQuery.append("(1=1) ");
}

if (queryRequest.getSaddleWidthOptions() != null &&


queryRequest.getSaddleWidthOptions().size() > 0) {
// Build saddle clause
averagesQuery.append(" AND (saddle_width IN (");
if
("on".equalsIgnoreCase(queryRequest.getSaddleWidthOptions().get("sw130")) ) {
averagesQuery.append("130,");
}
if
("on".equalsIgnoreCase(queryRequest.getSaddleWidthOptions().get("sw143")) ) {
averagesQuery.append(" 143,");
}
if
("on".equalsIgnoreCase(queryRequest.getSaddleWidthOptions().get("sw155")) ) {
BODY GEOMETRY DATA 41

averagesQuery.append(" 155,");
}
if
("on".equalsIgnoreCase(queryRequest.getSaddleWidthOptions().get("sw168")) ) {
averagesQuery.append(" 168,");
}
if (averagesQuery.lastIndexOf(",") >= 0){

averagesQuery.deleteCharAt(averagesQuery.lastIndexOf(","));
}
averagesQuery.append("))");
}

if (queryRequest.getRideFreqOptions() != null &&


queryRequest.getRideFreqOptions().size() > 0) {
// Build ride frequency clause
averagesQuery.append(" AND (riding_frequency IN (");
if
("on".equalsIgnoreCase(queryRequest.getRideFreqOptions().get("mo1_3")) ) {
averagesQuery.append("\"1-3 times per month\",");
}
if
("on".equalsIgnoreCase(queryRequest.getRideFreqOptions().get("w1_2")) ) {
averagesQuery.append("\"1-2 times per week\",");
}
if
("on".equalsIgnoreCase(queryRequest.getRideFreqOptions().get("w3_5")) ) {
averagesQuery.append("\"3-5 times per week\",");
}
if ("on".equalsIgnoreCase(queryRequest.getRideFreqOptions().get("w6"))
){
averagesQuery.append("\"6 times per week\",");
BODY GEOMETRY DATA 42

}
if
("on".equalsIgnoreCase(queryRequest.getRideFreqOptions().get("moLess")) ) {
averagesQuery.append("\"less than once a month\",");
}
if (averagesQuery.lastIndexOf(",") >= 0){

averagesQuery.deleteCharAt(averagesQuery.lastIndexOf(","));
}
averagesQuery.append("))");
}

if (queryRequest.getRideDurationOptions() != null &&


queryRequest.getRideDurationOptions().size() > 0) {
// Build ride-duration clause
averagesQuery.append(" AND (riding_duration IN (");
if
("on".equalsIgnoreCase(queryRequest.getRideDurationOptions().get("min0_30")) ) {
averagesQuery.append("\"0-30 minutes\",");
}
if
("on".equalsIgnoreCase(queryRequest.getRideDurationOptions().get("min30_90")) ) {
averagesQuery.append("\"30-90 minutes\",");
}
if
("on".equalsIgnoreCase(queryRequest.getRideDurationOptions().get("min90")) ) {
averagesQuery.append("\"90+ minutes\",");
}
if (averagesQuery.lastIndexOf(",") >= 0){

averagesQuery.deleteCharAt(averagesQuery.lastIndexOf(","));
}
BODY GEOMETRY DATA 43

averagesQuery.append("))");
}

if (queryRequest.getCategoryOptions() != null &&


queryRequest.getCategoryOptions().size() > 0) {
// Build ride-duration clause
averagesQuery.append(" AND (category IN (");
if
("on".equalsIgnoreCase(queryRequest.getCategoryOptions().get("comm_comfort")) ) {
averagesQuery.append("\"commute-comfort\",");
}
if
("on".equalsIgnoreCase(queryRequest.getCategoryOptions().get("comm_sport")) ) {
averagesQuery.append("\"commute-sport\",");
}
if
("on".equalsIgnoreCase(queryRequest.getCategoryOptions().get("cyclocross")) ) {
averagesQuery.append("\"cyclocross\",");
}
if
("on".equalsIgnoreCase(queryRequest.getCategoryOptions().get("mtb_trail")) ) {
averagesQuery.append("\"mtb-trail\",");
}
if
("on".equalsIgnoreCase(queryRequest.getCategoryOptions().get("mtb_xc")) ) {
averagesQuery.append("\"mtb-xc\",");
}
if
("on".equalsIgnoreCase(queryRequest.getCategoryOptions().get("road")) ) {
averagesQuery.append("\"road\",");
}
if
("on".equalsIgnoreCase(queryRequest.getCategoryOptions().get("triathlon")) ) {
BODY GEOMETRY DATA 44

averagesQuery.append("\"triathlon\",");
}
if (averagesQuery.lastIndexOf(",") >= 0){

averagesQuery.deleteCharAt(averagesQuery.lastIndexOf(","));
}
averagesQuery.append("))");
}

// (end Where clause)


averagesQuery.append(")");
return averagesQuery.toString();
}
}

QueryRequestOptions.java:
package com.mine.demo.sample.model;

public class QueryRequestOptions {


public static final String SIT_BONE_MEASURE = "Sit-bone measurement";
public static final String GENDER = "Gender";
public static final String SADDLE_SIZE = "Saddle size";
public static final String ALL_TESTS = "All tests";
public static final String RIDER_AVGS = "Each rider's average";
public static final String AVERAGE_AND_COUNT = "Average & How many";
}

SitBoneAnalysisResultPOJO.java:
package com.mine.demo.sample.model;

public class SitBoneAnalysisResultPOJO {

private String whatQueried = QueryRequestOptions.SIT_BONE_MEASURE;


private String whatResult = QueryRequestOptions.AVERAGE_AND_COUNT;
private String avgMeasure;
private String howManyMeasures;
private QueryRequest queryRequest;

public SitBoneAnalysisResultPOJO() {
super();
BODY GEOMETRY DATA 45

public String getWhatQueried() {


return whatQueried;
}

public String getWhatResult() {


return whatResult;
}

public String getAvgMeasure() {


return avgMeasure;
}

public void setAvgMeasure(String avgMeasure) {


this.avgMeasure = avgMeasure;
}

public String getHowManyMeasures() {


return howManyMeasures;
}

public void setHowManyMeasures(String howManyMeasures) {


this.howManyMeasures = howManyMeasures;
}

public QueryRequest getQueryRequest() {


return queryRequest;
}

public void setQueryRequest(QueryRequest queryRequest) {


this.queryRequest = queryRequest;
}

QueryRequest.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"%>
<%@ page import="com.mine.demo.sample.model.QueryRequest" %>
<%@ page import="com.mine.demo.sample.model.SitBoneAnalysisResultPOJO" %>

<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>


<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<jsp:useBean id="queryRequest" type="com.mine.demo.sample.model.QueryRequest"


scope="session" />
<jsp:useBean id="sbAnalysisResult"
type="com.mine.demo.sample.model.SitBoneAnalysisResultPOJO" scope="session" />

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">


<html>
BODY GEOMETRY DATA 46

<head>
<title>Sit Bone Analysis</title>
</head>
<body>

<h2>${sbAnalysisResult.whatQueried} ${sbAnalysisResult.whatResult }:</h2>


<table border = '1'>
<tr><th>Average</th><th>How many ${sbAnalysisResult.whatQueried}
averaged</th></tr>
<tr>
<fmt:formatNumber var="average" type="number" maxIntegerDigits="3"
minFractionDigits="4" value="${sbAnalysisResult.avgMeasure}" />
<fmt:formatNumber var="count" type="number" maxIntegerDigits="6"
value="${sbAnalysisResult.howManyMeasures}" />
<td><c:out value="${average}" /></td>
<td><c:out value="${count}" /></td>
</tr>
</table>
<p>
<form method = "post" action = "/BeyondDemo/averages" >
<h3>Select your next query parameters:</h3>
<table border = '1'>
<tr><th>Gender</th><th>Saddle width</th><th>Ride
frequency</th><th>Category</th><th>Ride Duration</th></tr>
<tr>
<td><input type="checkbox" name="gender" value="male" <c:if
test="${queryRequest.genderOptions.get('male') == 'on'}">checked="checked"</c:if>
/>Male<p>
<input type="checkbox" name="gender" value="female" <c:if
test="${queryRequest.genderOptions.get('female') == 'on'}">checked="checked"</c:if>
/>Female
</td>
<td><input type="checkbox" name="saddleWidth" value="sw130" <c:if
test="${queryRequest.saddleWidthOptions.get('sw130') ==
'on'}">checked="checked"</c:if> />130<p>
<input type="checkbox" name="saddleWidth" value="sw143" <c:if
test="${queryRequest.saddleWidthOptions.get('sw143') ==
'on'}">checked="checked"</c:if>/>143<p>
<input type="checkbox" name="saddleWidth" value="sw155" <c:if
test="${queryRequest.saddleWidthOptions.get('sw155') ==
'on'}">checked="checked"</c:if>/>155<p>
<input type="checkbox" name="saddleWidth" value="sw168" <c:if
test="${queryRequest.saddleWidthOptions.get('sw168') ==
'on'}">checked="checked"</c:if>/>168
</td>
<td><input type="checkbox" name="rideFreq" value="mo1_3" <c:if
test="${queryRequest.rideFreqOptions.get('mo1_3') == 'on'}">checked="checked"</c:if>
/>1-3 rides per month<p>
<input type="checkbox" name="rideFreq" value="w3_5" <c:if
test="${queryRequest.rideFreqOptions.get('w3_5') == 'on'}">checked="checked"</c:if>
/>3-5 rides per week<p>
<input type="checkbox" name="rideFreq" value="w1_2" <c:if
test="${queryRequest.rideFreqOptions.get('w1_2') == 'on'}">checked="checked"</c:if>
/>1-2 rides per week<p>
BODY GEOMETRY DATA 47

<input type="checkbox" name="rideFreq" value="w6" <c:if


test="${queryRequest.rideFreqOptions.get('w6') == 'on'}">checked="checked"</c:if> />6
rides per week<p>
<input type="checkbox" name="rideFreq" value="moLess" <c:if
test="${queryRequest.rideFreqOptions.get('moLess') == 'on'}">checked="checked"</c:if>
/>less than one ride a month<p>
</td>
<td><input type="checkbox" name="rideCategory" value="comm_comfort"
<c:if test="${queryRequest.categoryOptions.get('comm_comfort') ==
'on'}">checked="checked"</c:if> />Commuter (Comfort)<p>
<input type="checkbox" name="rideCategory" value="comm_sport"
<c:if test="${queryRequest.categoryOptions.get('comm_sport') ==
'on'}">checked="checked"</c:if> />Commuter (Sport)<p>
<input type="checkbox" name="rideCategory" value="cyclocross"
<c:if test="${queryRequest.categoryOptions.get('mtb_trail') ==
'on'}">checked="checked"</c:if> />Cyclocross<p>
<input type="checkbox" name="rideCategory" value="mtb_trail"
<c:if test="${queryRequest.categoryOptions.get('mtb_xc') ==
'on'}">checked="checked"</c:if> />MTB (Trail)<p>
<input type="checkbox" name="rideCategory" value="mtb_xc" <c:if
test="${queryRequest.categoryOptions.get('mtb_xc') == 'on'}">checked="checked"</c:if>
/>MTB (XC)<p>
<input type="checkbox" name="rideCategory" value="road" <c:if
test="${queryRequest.categoryOptions.get('road') == 'on'}">checked="checked"</c:if>
/>Road<p>
<input type="checkbox" name="rideCategory" value="triathlon"
<c:if test="${queryRequest.categoryOptions.get('triathlon') ==
'on'}">checked="checked"</c:if> />Triathlon<p>
</td>
<td><input type="checkbox" name="rideDuration" value="min0_30" <c:if
test="${queryRequest.rideDurationOptions.get('min0_30') ==
'on'}">checked="checked"</c:if> />0-30 Minutes<p>
<input type="checkbox" name="rideDuration" value="min30_90" <c:if
test="${queryRequest.rideDurationOptions.get('min30_90') ==
'on'}">checked="checked"</c:if> />30-90 Minutes<p>
<input type="checkbox" name="rideDuration" value="min90" <c:if
test="${queryRequest.rideDurationOptions.get('min90') ==
'on'}">checked="checked"</c:if> />90+ minutes<p>
</td>
</tr>
</table>
<p>
<c:set var="queryRequest" value="${queryRequest}" scope="session" />
<p><input type="submit" value="submit"/>
</form>
<p>
</body>
</html>

Vous aimerez peut-être aussi