Projet MIAGE Projet de l'année 2013-2014.

Inria Miage

Réalisation d'une application Web de consultation de données Open Data géolocalisées (recensement des résidences hôtelières).

Attention Problèmes de performance

Suite aux problèmes de performances remontés par certains d'entre-vous avec l'utilisation d'eXist et le jeu de données proposé, les changements suivants sont appliqués :

  • le jeu de données a été changé ; le nouveau est moins plat et moins volumineux.
  • vous pouvez au choix utiliser BaseX ou eXist pour stocker ces données.

Pour tordre le cou à quelques conclusions hâtives

Performance des BD Elements de comparaison.

Ce document compare les performances de quelques BD (eXist, BaseX, Mysql), sans avoir la prétention de se positionner comme un benchmark complet.

Voir »

Enoncé

On dispose de données géolocalisées de résidences hôtelières dans le département. On vous demande de réaliser une application Web de consultation de ces données.

Conditions de réalisation

Ces données doivent être chargées dans une base de données native XML ; vous utiliserez eXist-db ou BaseX (au choix) ; toutes les requêtes d'extraction des données seront faites en XQuery. L'utilisation d'une base de données relationnelle est proscrite.

Vous pouvez utiliser un serveur Web (Tomcat) supplémentaire entre la base de données et le client. Dans le contexte de ce projet ce n'est pas une obligation, mais peut se révéler pratique notamment pour opérer les transformations XML -> XSLFO avec XSLT puis XSLFO -> PDF avec FOP. L'utilisation de PHP est à proscrire.

Info Serveurs Web et serveur d'appli

eXist est à part entière un serveur d'application, un serveur de base de données XML, et un serveur Web ; il peut sembler inutile d'ajouter en frontal un autre serveur Web.

Notez que c'est une pratique courante pour des raisons de sécurité d'utiliser un serveur Web Apache httpd en frontal afin d'éviter d'exposer directement un serveur d'application ou une BD sur le Web, et qui ont vocation à être déployés derrière la DMZ.

Côté client, vous pouvez utiliser des librairies telles que jQuery ; le recours à JSON est proscrit pour accéder aux données provenant de la base de données. Si vous utilisez GWT, l'utilisation de RPC est proscrit.

Téléchargez le fichier XML et chargez-le dans la BD eXist ou BaseX.

Extrait du fichier :

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<entries xmlns="http://ref.otcnice.com/webservice/" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:SchemaLocation="http://ref.otcnice.com/webservice/entries.xsd">

  <entry>
    <ID>1021</ID>
    <name_fr>AC BY MARRIOTT NICE</name_fr>
    <name_fr_short>AC BY MARRIOTT NICE</name_fr_short>
    <address>
      <address_line1>59 Promenade des Anglais</address_line1>
      <address_line2/>
      <address_line3/>
      <zip>06000</zip>
      <city>NICE</city>
    </address>
    <phone>+33 (0)4 93 97 90 90</phone>
    <fax>+33 (0)4 93 44 06 55</fax>
    <email>ac.nceac.exec.sec@marriott.com</email>
    <website>http://www.achotelnice.com</website>
    <contacts/>
    <payments>
      <payment>Visa</payment>
      <payment>Master Card</payment>
      <payment>American express</payment>
      <payment>Diner's club</payment>
      <payment>Chèques</payment>
      <payment>Chèques Vacances</payment>
      <payment>Espèces</payment>
      <payment>Virements</payment>
      <payment>Chèques de voyage</payment>
      <payment>Carte de crédit</payment>
    </payments>
    <languages>
      <language>Anglais</language>
      <language>Allemand</language>
      <language>Espagnol</language>
      <language>Italien</language>
      <language>Russe</language>
      <language>Français</language>
      <language>Néerlandais</language>
      <language>Arabe</language>
      <language>Finois</language>
      <language>Portugais</language>
    </languages>
    <labels>
      <label>Nice Irisée Naturellement</label>
    </labels>
    <amenities>
      <amenity>Accès Internet</amenity>
      <amenity>Ascenseur</amenity>
      <amenity>Bar</amenity>
      <amenity>Bibliothèque</amenity>
      <amenity>Boutique</amenity>
      <amenity>Garage privé</amenity>
      <amenity>Jardin</amenity>
      <amenity>Equipements pour enfants</amenity>
      <amenity>Local matériel fermé</amenity>
      <amenity>Parking privé</amenity>
      <amenity>Parking public à proximité</amenity>
      <amenity>Piscine</amenity>
      <amenity>Restaurant</amenity>
      <amenity>Salle de sport</amenity>
      <amenity>Salon</amenity>
      <amenity>Salon de télévision</amenity>
      <amenity>Terrasse</amenity>
      <amenity>Wifi</amenity>
      <amenity>Accès Internet dans les chambres</amenity>
      <amenity>Animaux acceptés</amenity>
      <amenity>Blanchisserie</amenity>
      <amenity>Bureau de change</amenity>
      <amenity>Câble, satellite</amenity>
      <amenity>Climatisation</amenity>
      <amenity>Coffres clients</amenity>
      <amenity>Double vitrage</amenity>
      <amenity>Réservation de prestations</amenity>
      <amenity>Service en chambre</amenity>
      <amenity>Téléphone</amenity>
      <amenity>Télévision</amenity>
      <amenity>Veilleur de nuit</amenity>
      <amenity>Voiturier</amenity>
      <amenity>Accueil enfants</amenity>
      <amenity>Menu Enfants</amenity>
      <amenity>Salle de réunion</amenity>
      <amenity>Chambres vue mer</amenity>
      <amenity>Chambres communicantes / familiales</amenity>
      <amenity>Piscine réservée à la clientèle</amenity>
      <amenity>Equip. personnes handicapées</amenity>
      <amenity>Toit-terrasse</amenity>
    </amenities>
    <profiles>
      <profile>Handicapé</profile>
      <profile>Couples</profile>
    </profiles>
    <locations>
      <location>Aéroport</location>
      <location>Magnan</location>
      <location>Nice Ouest</location>
      <location>Gambetta</location>
      <location>Centre Ville</location>
    </locations>
    <categories>
      <category>Hôtels de tourisme</category>
      <category>Hôtels pour conférence</category>
      <category>NN</category>
    </categories>
    <stations>
      <station>Grosso CUM - Promenade</station>
      <station>Grosso CUM</station>
      <station>Grosso CUM</station>
    </stations>
    <standings_levels>
      <standings_level>4 étoiles</standings_level>
    </standings_levels>
    <options>
      <option>Accès handicapés</option>
    </options>
    <publications>
      <publication>Meeting guide</publication>
      <publication>Hébergement</publication>
      <publication>Nice irisée naturellement</publication>
    </publications>
    <common_tags>
      <common_tag>Rencontres professionnelles</common_tag>
    </common_tags>
    <descriptions/>
    <images>
      <image>http://www.nicetourisme.com/public/resources/directory/entries/photos/ref/191809.jpg</image>
      <image>http://www.nicetourisme.com/public/resources/directory/entries/photos/ref/191814.jpg</image>
      <image>http://www.nicetourisme.com/public/resources/directory/entries/photos/ref/191813.jpg</image>
      <image>http://www.nicetourisme.com/public/resources/directory/entries/photos/ref/191810.jpg</image>
      <image>http://www.nicetourisme.com/public/resources/directory/entries/photos/ref/191811.jpg</image>
      <image>http://www.nicetourisme.com/public/resources/directory/entries/photos/ref/191812.jpg</image>
      <image>http://www.nicetourisme.com/public/resources/directory/entries/photos/ref/191815.jpg</image>
    </images>
    <living>
      <room_count>143</room_count>
      <room_bath_count>0</room_bath_count>
      <room_shower_count>143</room_shower_count>
      <suite_count>22</suite_count>
      <studio_count>0</studio_count>
      <apartment_count>0</apartment_count>
      <room_accessible_count>7</room_accessible_count>
      <single_count>0</single_count>
      <double_count>0</double_count>
      <triple_count>0</triple_count>
      <twins_count>0</twins_count>
      <family_count>0</family_count>
      <area>0</area>
      <type>94 singles = doubles - 49 twins - 22 triples - 61 vue mer</type>
      <floor>0</floor>
      <bedroom_count>0</bedroom_count>
      <sleeps_count>0</sleeps_count>
      <furnished_room_count>0</furnished_room_count>
    </living>
    <tariffs>
      <tariff>
        <name>Chambre simple</name>
        <unique>0</unique>
        <min>120</min>
        <max>500</max>
        <average>0</average>
        <fixed>0</fixed>
      </tariff>
      <tariff>
        <name>Chambre double</name>
        <unique>0</unique>
        <min>120</min>
        <max>500</max>
        <average>0</average>
        <fixed>0</fixed>
      </tariff>
      <tariff>
        <name>Petit déjeuner</name>
        <unique>0</unique>
        <min>0</min>
        <max>21</max>
        <average>0</average>
        <fixed>0</fixed>
      </tariff>
    </tariffs>
    <capacity>
      <total>0</total>
      <indoor>0</indoor>
      <outdoor>0</outdoor>
      <group>120</group>
      <room_count>3</room_count>
      <disabled_count>0</disabled_count>
    </capacity>
    <closures/>
    <spaces/>
    <opening/>
    <closing/>
    <latitude>43.6931</latitude>
    <longitude>7.25298</longitude>
    <location_map>G5</location_map>
    <note>4</note>
    <niceres_availability>true</niceres_availability>
    <niceres_id>911</niceres_id>
    <created>2012-05-03 11:28:24</created>
    <updated>2013-09-13 15:49:00</updated>
  </entry>

</entries>

C'était comment, avant ?

Projet MIAGE Projet de l'année 2012-2013.

Réalisation d'une application Web de consultation de mesures géolocalisées de température et d'hygrométrie.

Voir »

Un fichier W3C XML Schema est également disponible :

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<xsd:element name="entries">
		<xsd:complexType mixed="true">
			<xsd:choice maxOccurs="unbounded" minOccurs="1">
				<xsd:element name="entry">
					<xsd:complexType mixed="true">
						<xsd:sequence>
							<xsd:element name="id" type="xsd:integer"/>
							<xsd:element name="name_fr" type="xsd:string"/>
							<xsd:element name="name_fr_short" type="xsd:string"/>
							<xsd:element name="adress" type="xsd:string"/>
							<xsd:element name="zip" type="xsd:string"/>
							<xsd:element name="city" type="xsd:string"/>
							<xsd:element name="phone" type="xsd:string"/>
							<xsd:element name="fax" type="xsd:string"/>
							<xsd:element name="email" type="xsd:string"/>
							<xsd:element name="website" type="xsd:string"/>

														
							<xsd:element name="contacts">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
									    <xsd:element name="contact">
				                       	<xsd:complexType mixed="true">
											<xsd:sequence>
												<xsd:element name="civility" type="xsd:string"/>
												<xsd:element name="name" type="xsd:string"/>
												<xsd:element name="title" type="xsd:string"/>
												<xsd:element name="function" type="xsd:string"/>
												<xsd:element name="phone" type="xsd:string"/>
												<xsd:element name="email" type="xsd:string"/>
											</xsd:sequence>
										</xsd:complexType>
										</xsd:element>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
							
							
							
							<xsd:element name="payments">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="payment" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
							
														
							<xsd:element name="labels">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="label" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
							
							
							<xsd:element name="amenities">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="amenity" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
							
														
							
							<xsd:element name="profiles">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="profile" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
														
														
							
							<xsd:element name="locations">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="location" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
																					
														
							
							<xsd:element name="activities">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="activity" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
							
							
							<xsd:element name="categories">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="1">
										<xsd:element name="category" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
														
														
							
							<xsd:element name="affiliations">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="affiliation" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
							
							
							<xsd:element name="stations">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="station" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
																				
																					
							<xsd:element name="standings_levels">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="standings_level" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
									
																													
							<xsd:element name="chains">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="chain" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>	
									
													
							<xsd:element name="services">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="service" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
																								
																					
							<xsd:element name="options">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="option" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
										
																															
							<xsd:element name="FRP_options">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="FRP_option" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
							
																																						
							<xsd:element name="POI_options">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="POI_option" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
																													
																					
							<xsd:element name="publications">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="publication" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
							
							
							<xsd:element name="descriptions">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="description">
				                       	<xsd:complexType>
				                       			<xsd:simpleContent>
				                       				<xsd:extension base="xsd:string">
				                       					<xsd:attribute name="language" type="xsd:string" use="required"/>
														<xsd:attribute name="type" type="xsd:string" use="required"/>
													</xsd:extension>
												</xsd:simpleContent>
										</xsd:complexType>
										</xsd:element>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
							


							<xsd:element name="chains">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="chain" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>						
							
							
							
							<xsd:element name="images">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="image" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
						
							
							<xsd:element name="living">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="room_count" type="xsd:integer"/>
										<xsd:element name="room_bath_count" type="xsd:integer"/>
										<xsd:element name="room_shower_count" type="xsd:integer"/>
										<xsd:element name="room_nosmoking_count" type="xsd:integer"/>
										<xsd:element name="suite_count" type="xsd:integer"/>
										<xsd:element name="studio_count" type="xsd:integer"/>
										<xsd:element name="apartment_count" type="xsd:integer"/>
										<xsd:element name="area" type="xsd:integer"/>
										<xsd:element name="type" type="xsd:string"/>
										<xsd:element name="floor" type="xsd:integer"/>
										<xsd:element name="bedroom_count" type="xsd:integer"/>
										<xsd:element name="sleeps_count" type="xsd:integer"/>
										<xsd:element name="furnished_room_count" type="xsd:integer"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
							
				
								
							<xsd:element name="tariffs">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
									    <xsd:element name="tariff">
				                       	<xsd:complexType mixed="true">
											<xsd:sequence>
												<xsd:element name="name" type="xsd:string"/>
												<xsd:element name="unique" type="xsd:integer"/>
												<xsd:element name="min" type="xsd:integer"/>
												<xsd:element name="max" type="xsd:integer"/>
												<xsd:element name="average" type="xsd:integer"/>
												<xsd:element name="fixed" type="xsd:integer"/>
											</xsd:sequence>
										</xsd:complexType>
										</xsd:element>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
																													
						
							
							<xsd:element name="capacity">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="total" type="xsd:integer"/>
										<xsd:element name="indoor" type="xsd:integer"/>
										<xsd:element name="group" type="xsd:integer"/>
										<xsd:element name="room_count" type="xsd:integer"/>
										<xsd:element name="disabled_count" type="xsd:integer"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
													
							
							<xsd:element name="spaces">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
									    <xsd:element name="space">
				                       	<xsd:complexType mixed="true">
											<xsd:sequence>
												<xsd:element name="name" type="xsd:string"/>
												<xsd:element name="capacity_theater" type="xsd:integer"/>
												<xsd:element name="capacity_classroom" type="xsd:integer"/>
												<xsd:element name="capacity_u" type="xsd:integer"/>
												<xsd:element name="capacity_cocktail" type="xsd:integer"/>
												<xsd:element name="capacity_seatedmeal" type="xsd:integer"/>
												<xsd:element name="ceiling_height" type="xsd:integer"/>
												<xsd:element name="is_natural_light" type="xsd:integer"/>
												<xsd:element name="area" type="xsd:integer"/>
													<xsd:element name="resources">
													<xsd:complexType mixed="true">
														<xsd:choice maxOccurs="unbounded" minOccurs="0">
															<xsd:element name="resource_path" type="xsd:string"/>
														</xsd:choice>
													</xsd:complexType>
													</xsd:element>
											</xsd:sequence>
										</xsd:complexType>
										</xsd:element>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
							
							
							<xsd:element name="opening">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="opening" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>

							<xsd:element name="closing">
								<xsd:complexType mixed="true">
									<xsd:choice maxOccurs="unbounded" minOccurs="0">
										<xsd:element name="closing" type="xsd:string"/>
									</xsd:choice>
								</xsd:complexType>
							</xsd:element>
							
							<xsd:element name="latitude" type="xsd:decimal"/>
							<xsd:element name="longitude" type="xsd:decimal"/>
							<xsd:element name="location_map" type="xsd:string"/>
							<xsd:element name="note" type="xsd:string"/>
							<xsd:element name="niceres_availability" type="xsd:boolean"/>
							<xsd:element name="niceres_id" type="xsd:integer"/>
														
							<xsd:element name="created" type="xsd:string"/>
							<xsd:element name="updated" type="xsd:string"/>
							
						</xsd:sequence>
					</xsd:complexType>
				</xsd:element>
			</xsd:choice>
		</xsd:complexType>
	</xsd:element>
</xsd:schema>

Application

Faites l'application que vous jugerez intéressante. Elle doit au moins :

  • permettre de naviguer dans les données
  • les présenter dans un Map (GoogleMap, OpenStreetMap, etc).
  • délivrer des données statistiques sous forme de tableau et graphiques faits en SVG
  • permettre d'extraire un rapport PDF contenant des graphiques SVG, en le produisant en XSLFO grâce à XSLT

Il s'agit du minimum requis, mais vous pouvez trouver vous-mêmes d'autres choses intéressantes à faire avec ces données, comme par exemple chercher un autre dataset et croiser les données avec cet autre jeu de données.

Déroulement du projet

Groupes : 3 individus

Date de début : 15/11/2013

Date de fin : date à définir en janvier 2014

Livrables : un rapport (2 pages) décrivant les aspect techniques de votre projet et les fonctionalités principales, à restituer une semaine avant la démo

Démo : présenter une appli qui marche ; vous devez aussi pouvoir montrer le code de votre appli

Aide Forum

Un forum est à votre disposition ; vous pouvez y poser toutes les questions concernant les aspects techniques, organisationels, ou métaphysiques concernant le projet. Il y a aussi un espace pour déclarer vos équipes projets, et un espace pour rechercher un partenaire. Concernant les questions, tout le monde est invité à poster les réponses aux questions posées par les autres (ça donnera des points en plus). Avant de poser une question, n'hésitez pas à consulter le forum au préalable !